package com.enzoism.springboot.dive.a01callable.a02asyntask;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

/**
 * 程序设计的时候应该敏感的将【数据再加工方法】放到外部进行操作，否则不好Mock
 * 1）使用AsynTaskService进行外部接口调用
 * 2）使用callable进行异步数据的获取
 */
@Service
public class AsynTaskServiceHelper {
    @Autowired
    private AsynTaskService asynTaskService;

    /**
     * 简单模拟rest接口的外部调用/数据库的真实操作
     */
    public List<String> getASynRestApiListResult() {

        // 创建异步线程池
        int threadSize = 5;
        ExecutorService executorService = Executors.newFixedThreadPool(threadSize);
        CompletionService<String> completionService = new ExecutorCompletionService(executorService);

        // 进行异步请求
        for (int i = 0; i < threadSize; i++) {
            completionService.submit(new AsynTaskCallable("系统编号00" + i, asynTaskService));
        }

        // 进行异步结果获取
        List<String> list = new ArrayList<>();
        for (int i = 0; i < threadSize; i++) {
            String str = getASynRestApiFromCompletionService(completionService);
            System.out.println("----->异步线程执行结果：" + str);
            list.add(str);
        }

        // 线程池销毁
        executorService.shutdown();

        return list;
    }

    private String getASynRestApiFromCompletionService(CompletionService<String> completionService) {
        String result = null;
        try {
            result = completionService.take().get();
        } catch (InterruptedException e) {
            // 注意：SonarQu推荐使用Thread.currentThread().interrupt();
            // 但是最好不要，进行可能会产生其他莫名奇妙的错误，尤其是框架多层封装
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        result = StringUtils.isEmpty(result) ? "默认返回值" : result;
        return result;
    }
}
